//
// Created by tang on 23-4-1.
//

#include "ui_item.hpp"
#include "core/log.hpp"
#include "imgui.h"
#include "style/ui_style.hpp"
#include "ui_registry.hpp"

#include "utils/string_utils.hpp"

ui_item::ui_item (ui_item *parent): parent_ (parent)
{
}

void ui_item::draw () {
    ImGui::PushID(this);
    before_draw();

    if (style_) {
        style_->use();
    }
    if (options_) {
        options_->use();
    }
    draw_self();
    if (style_)
        style_->revert(style_mode::self_only);
    draw_children();
    if (style_)
        style_->revert(style_mode::with_child);

    after_draw();

    if (options_)
        options_->revert();

    ImGui::PopID();
}

void ui_item::init_by_xml_node (const xml_node &node)
{
    // parse style & options
    style_ = ui_style::create_from_node(node);
    options_ = ui_options::create_from_node(node);

    // self content
    init_content(node);
}

ui_item * ui_item::create_ui (const pugi::xml_node &node, ui_item *parent)
{
    static auto       factories = get_ui_factories();
    ui_item*          ret       = nullptr;
    const std::string name      = to_lower(node.name());
    if (const auto it = factories->find (name); it != end(*factories)) {
        ret = it->second(parent);
        if (ret)
            ret->init_by_xml_node (node);
    } else if (name != "styles") {
        L_ERROR ("Unknown ui type: %s", name.c_str());
    }
    return ret;
}

using pfn_item_creator = ui_item* (*)();

ui_item *ui_item::create_ui (const u8 *data, size_t length, ui_item* parent)
{
    using namespace pugi;

    ui_item *ret = nullptr;
    xml_document doc;
    if (auto r = doc.load_buffer (data, length)) {
        auto root = doc.document_element();
        ret = create_ui(root, parent);
    } else {
        L_WARN("Xml parse error: %s", r.description());
    }

    return ret;
}

void ui_item::draw_children ()
{
    // default no children
}

void ui_item::before_draw()
{

}

void ui_item::after_draw()
{

}
